// 导入模块 Import modules
import { StorageTypes } from './enum/manager';

/**
 * @zh 数据空间管理基类
 * @en Base class for data space management
 * @author Lusisi卢喜喜 <3986410685@qq.com>
 */
class StorageManager<T = JSONValue> {
    /**
     * @zh 数据空间
     * @en Data space
     */
    private storage: GameDataStorage<T>;

    /**
     * @zh 数据空间类型
     * @en Type of data space
     */
    private storageType: StorageTypes;

    /**
     * @zh 构造函数
     * @param storageKey 存储空间键名
     * @param storageType 存储空间类型
     * @en Public constructor
     * @param storageKey Storage space key name
     * @param storageType Whether it's a group storage space
     */
    public constructor(
        storageKey: string,
        storageType: StorageTypes = StorageTypes.Common
    ) {
        if (storageType === StorageTypes.Group) {
            this.storage = storage.getGroupStorage<T>(storageKey)!;
            this.storageType = storageType;
        } else {
            this.storage = storage.getDataStorage<T>(storageKey);
            this.storageType = storageType;
        }
    }

    /**
     * @zh 设置指定键的值
     * @param key 键名
     * @param value 要设置的值
     * @en Set value for specified key
     * @param key Key name
     * @param value Value to set
     */
    public async set(key: string, value: T): Promise<void> {
        await this.storage.set(key, value);
    }

    /**
     * @zh 获取指定键的值
     * @param key 键名
     * @returns 返回键对应的值
     * @en Get value for specified key
     * @param key Key name
     * @returns Returns value for the key
     */
    public async get(key: string): Promise<ReturnValue<T>> {
        return await this.storage.get(key);
    }

    /**
     * @zh 使用处理器函数更新指定键的值
     * @param key 键名
     * @param value 新的值
     * @en Update value using handler function
     * @param key Key name
     * @param value New value
     */
    public async update(key: string, value: T): Promise<void> {
        await this.storage.update(key, () => value);
    }

    /**
     * @zh 获取存储空间键名
     * @returns 返回存储空间键名
     * @en Get storage space key name
     * @returns Returns storage space key name
     */
    public getStorageKey(): string {
        return this.storage.key;
    }

    /**
     * @zh 获取存储空间类型
     * @returns 返回存储空间类型
     * @en Get type of storage space
     * @returns Returns type of storage space
     */
    public getStorageType(): StorageTypes {
        return this.storageType;
    }

    /**
     * @zh 获取存储空间的所有数据
     * @returns 返回存储空间的所有数据
     * @en Get all data within storage space
     * @returns Returns all data within storage space
     */
    public async getDataList(): Promise<ReturnValue<T>[]> {
        const queryList: QueryList<T> = await this.storage.list({
            cursor: 0,
            pageSize: 10,
        });
        const dataList: ReturnValue<T>[] = [];
        while (true) {
            dataList.push(...queryList.getCurrentPage());
            if (queryList.isLastPage) {
                break;
            }
            await queryList.nextPage();
        }
        return dataList;
    }

    /**
     * @zh 销毁存储空间
     * @en Destroy storage space
     */
    public async destroyStorage(): Promise<void> {
        await this.storage.destroy();
    }
}

// 导出模块 Export modules
export { StorageManager };
